// i discussed the algorithm and implementation with my friends cjxgm,
// and i copyed his c++ abstrat and implementation.
// even though in c++03, is's elegant.
//
// run: $exec < input
// std: c++03
#include <iostream>
#include <iterator>
#include <utility>
#include <complex>
#include <cmath>
#include <vector>
#include <set>

namespace tue
{
	static double const tolerance = 1e-15;

	inline bool almost(double a, double b) { return (std::abs(a-b) < tolerance); }

	inline double adj(double x, double y)
	{
		x = std::abs(x);
		y = std::abs(y);
		if (x < y) std::swap(x, y);
		y /= x;
		return x * std::sqrt(1 - y*y);
	}

	inline double cos(double a, double b, double oppo)
	{
		double x = a / b;
		double y = b / a;
		a = oppo / a;
		b = oppo / b;
		return (x + y - a*b) / 2.0f;
	}


	typedef std::complex<double> vec2;

	inline std::istream & operator >> (std::istream & i, vec2 & a)
	{
		double x, y;
		i >> x >> y;
		a = vec2(x, y);
		return i;
	}

	struct tolerant_less
	{
		bool operator () (vec2 const& a, vec2 const& b)
		{
			if (a.real() < b.real() - tolerance) return true;
			if (a.real() > b.real() + tolerance) return false;
			return (a.imag() < b.imag() - tolerance);
		}
	};

	inline double dot(vec2 const& a, vec2 const& b) { return a.real()*b.real() + a.imag()*b.imag(); }
	inline double len(vec2 const& a) { return std::abs(a); }
	inline vec2 rotator(double cos) { return cos + adj(1, cos)*1I; }

	inline double intersect(vec2 const& p0, vec2 const& d0, vec2 const& p1, vec2 const& d1)
	{
		double dot01 = dot(d0, d1);
		if (almost(dot01, 1)) return INFINITY;

		vec2 perp = d0 - dot01 * d1;
		return dot(p1-p0, perp) / dot(d0, perp);
	}

	inline double intersect(double d, double r0, double r1)
	{
		double rdiff = r0 - r1;
		double rsum = r0 + r1;
		if (d < tolerance) return INFINITY;
		if (d < rdiff-tolerance) return INFINITY;
		if (d < rdiff+tolerance) return 1;
		if (d < rsum-tolerance) return cos(r0, d, r1);
		if (d < rsum+tolerance) return 1;
		return INFINITY;
	}

	inline void intersect(double & k0, double & k1,
			vec2 const& p, vec2 const& d, vec2 const& o, double r)
	{
		k0 = k1 = INFINITY;
		vec2 po = o - p;
		double dotdpo = dot(d, po);
		double dist = adj(len(po), dotdpo);
		if (dist > r+tolerance) return;
		if (dist > r-tolerance) { k0 = dotdpo; return; }
		double offset = adj(r, dist);
		k0 = dotdpo - offset;
		k1 = dotdpo + offset;
	}

	struct geometry
	{
		vec2 point;
		vec2 dir;
		double radius;
		bool extend_backward;
		bool extend_forward;

		geometry(std::istream & i, bool extb, bool extf)
			: extend_backward(extb)
			  , extend_forward(extf)
		{
			i >> point >> dir;
			dir -= point;
			radius = len(dir);
			dir /= radius;
		}

		geometry(std::istream & i) : dir(INFINITY, INFINITY)
		{
			i >> point >> radius;
		}

		vec2 at(double k) const { return point + k*dir; }
		bool is_circle() const { return isinf(dir.real()); }

		bool contains(vec2 const& p) const { return contains(dot(p-point, dir)); }

		bool contains(double k) const
		{
			if (!extend_backward && k < -tolerance       ) return false;
			if (!extend_forward  && k > +tolerance+radius) return false;
			return true;
		}
	};

	template <class OUTPUT_IT>
	inline void intersect_ss(OUTPUT_IT out, geometry const& a, geometry const& b)
	{
		double k = intersect(a.point, a.dir, b.point, b.dir);
		if (isinf(k)) return;
		if (!a.contains(k)) return;
		vec2 p = a.at(k);
		if (!b.contains(p)) return;
		*out++ = p;
	}

	template <class OUTPUT_IT>
	inline void intersect_sc(OUTPUT_IT out, geometry const& s, geometry const& c)
	{
		double k0, k1;
		intersect(k0, k1, s.point, s.dir, c.point, c.radius);
		if (!isinf(k0) && s.contains(k0)) *out++ = s.at(k0);
		if (!isinf(k1) && s.contains(k1)) *out++ = s.at(k1);
	}

	template <class OUTPUT_IT>
	inline void intersect_cc(OUTPUT_IT out, geometry const& c0, geometry const& c1)
	{
		if (c0.radius < c1.radius) return intersect_cc(out, c1, c0);

		vec2 p = c1.point - c0.point;
		double d = len(p);
		double c = intersect(d, c0.radius, c1.radius);

		if (isinf(c)) return;

		p *= c0.radius / d;
		if (c == 1) {
			*out++ = c0.point + p;
			return;
		}

		vec2 rr = rotator(c);
		*out++ = c0.point + p * rr;
		*out++ = c0.point + p * std::conj(rr);
	}

	// dispatcher
	template <class OUTPUT_IT>
	inline void intersect(OUTPUT_IT out, geometry const& a, geometry const& b)
	{
		bool ac = a.is_circle();
		bool bc = b.is_circle();
		if (ac && bc) return intersect_cc(out, a, b);
		if (!ac && !bc) return intersect_ss(out, a, b);
		if (ac) return intersect_sc(out, b, a);
		/* bc */ return intersect_sc(out, a, b);
	}
}

int main()
{
	std::ios::sync_with_stdio(false);

	typedef std::vector<tue::geometry>  geom_list;
	typedef std::set   <tue::vec2, tue::tolerant_less> point_list;
	typedef  geom_list::iterator  geom_iter;

	int nseg, nray, nline, ncircle;
	std::cin >> nseg >> nray >> nline >> ncircle;

	geom_list geoms;
	geoms.reserve(nseg + nray + nline + ncircle);

	while (nseg--) geoms.push_back(tue::geometry(std::cin, false, false));
	while (nray--) geoms.push_back(tue::geometry(std::cin, false, true));
	while (nline--) geoms.push_back(tue::geometry(std::cin, true, true));
	while (ncircle--) geoms.push_back(tue::geometry(std::cin));

	point_list points;
	for (geom_iter last=geoms.end(),it=geoms.begin(); it != last; ++it)
		for (geom_iter with=it+1; with != last; ++with)
			intersect(std::inserter(points, points.end()), *it, *with);

	std::cout << points.size() << "\n";
}

